import time
from appium.options.common import AppiumOptions
from appium.webdriver import WebElement
from appium.webdriver.webdriver import WebDriver
from selenium.common import NoSuchElementException
from selenium.webdriver import ActionChains


class BaseDriver(WebDriver):
    """
    Driver基础类
    封装常用的底层方法
    """
    IMPLICITLY_WAIT = 10

    def find_el(self, by: str, value: str):
        try:
            el = self.find_element(by, value)
            return el
        except NoSuchElementException:
            return None

    def find_and_click(self, by: str, value: str):
        """
        查找元素并点击
        :param by: 定位方式
        :param value: 定位表达式
        """
        self.find_element(by, value).click()

    def find_and_send_keys(self, by: str, value: str, text: str):
        """
        查找元素并输入内容
        :param text: 要输入的文本内容
        :param by: 定位方式
        :param value: 定位表达式
        """
        input_element = self.find_element(by, value)
        input_element.click()
        actions = ActionChains(self)
        actions.send_keys(text).perform()

    def find_and_reset(self, by: str, value: str, text: str):
        """
        查找元素并重置内容
        """
        ele = self.find_element(by, value)
        ele.clear()
        actions = ActionChains(self)
        actions.send_keys(text).perform()

    def vertical_swipe(self):
        """
        上下滑动窗口
        """
        window_size = self.get_window_size()
        width = window_size['width']
        height = window_size['height']

        # 设置滑动前后坐标位置
        start_x = width // 2
        start_y = int(height * 0.8)

        end_x = width // 2
        end_y = int(height * 0.2)

        # 滑动时间 单位毫秒
        duration = 1000
        self.swipe(start_x, start_y, end_x, end_y, duration)

    def vertical_swipe_find(self, by: str, value: str, timeout: int = 15) -> WebElement:
        """
        上下滑动并寻找元素
        """
        end_time = time.time() + timeout
        while True:
            current_time = time.time()
            if current_time >= end_time:
                raise Exception("timeout!")
            el = self.find_el(by, value)
            if el:
                return el
            self.vertical_swipe()

    def vertical_swipe_find_and_click(self, by: str, value: str, timeout: int = 15):
        self.vertical_swipe_find(by, value, timeout).click()

    def get_err_msg(self, by, value):
        err_el = self.find_el(by, value)
        if err_el:
            err_msg = err_el.text
            return err_msg


def create_driver(address: str, caps: dict[str, any]) -> BaseDriver:
    options = AppiumOptions()
    for key, value in caps.items():
        options.set_capability(key, value)
    driver = BaseDriver(address, options=options)
    driver.implicitly_wait(driver.IMPLICITLY_WAIT)
    return BaseDriver(address, options=options)
